/* 
 * File:   instancereader.h
 * Author: tomas
 *
 * Created on March 27, 2009, 10:44 AM
 */

#ifndef _INSTANCEREADER_H
#define	_INSTANCEREADER_H

#include <iostream>
#include <string>
#include <sstream>
#include <vector>

#include "Instance.h"
#include "horse.h"

class InstanceReader {
public:


    InstanceReader( std::istream& _is): m_is(_is)
	{
    }

    // precte instanci problemu ze streamu
    Instance readInstance()
	{
        std::cerr << "velikost sachovnice:" << std::endl;
        size_t velikostSachovnice = prectiCisla(prectiRadek(), 1).at(0);

        std::cerr << "penalizace:" << std::endl;
        // penalizace
        Instance::penalties_t penalities;
        for (size_t i = 0; i < velikostSachovnice; i++) {
            penalities.push_back( prectiCisla(prectiRadek(), velikostSachovnice) );
        }

        std::cerr << "pocet konu" << std::endl;
        size_t pocetKonu = prectiCisla(prectiRadek(), 1).at(0);

        std::cerr << "rozmisteni jezdcu" << std::endl;
        Instance::horses_t horses;
        for (size_t i = 0; i < pocetKonu; i++) {
            std::vector<size_t> rozmisteni = prectiCisla(prectiRadek(), 2);
            Horse h(i, rozmisteni.at(0), rozmisteni.at(1) );
            horses.push_back(h);
        }

        std::cerr << "pocet tahu:" << std::endl;
        size_t pocetTahu = prectiCisla(prectiRadek(), 1).at(0);

        return Instance(velikostSachovnice, pocetKonu, pocetTahu, penalities, horses);
    }

private:

    std::istream& m_is;

    /*
     *
     */
    std::vector<size_t> prectiCisla(const std::string& str, const size_t count) {

        std::vector<size_t> res;
        res.reserve(count);

        std::istringstream ss(str);

        int tmp, index = 0;
        bool dalsi = ss >> tmp;
        while (dalsi && index < count) {

            if (!dalsi) {
                std::cerr << "chyba pri cteni cisla" << std::endl;
                throw "Chyba vstupu";
            }
            res.push_back(tmp);
            dalsi = ss >> tmp;
            index++;
        }
        // precetla se vsechna cisla, ale na vstupu jeste neco je
        if (dalsi) {
            std::cerr << "chyba cteni radku: neprecten cely radek" << std::endl;
            throw "Chyba vstupu";
        }
        // na radku je malo cisel
        if (index < count) {
            std::cerr << "chyba cteni radku: malo cisel na radku" << std::endl;
            throw "Chyba vstupu";
        }

        return res;
    }

    // cte vstup po radcich, dokud neprecte nezakomentovanou hodnotu
    std::string prectiRadek() {
        bool precteno = false;
        std::string str;
        while (!precteno) {
            // cin >> str;
            if (! std::getline(m_is, str) )
                return "";

            // odstraneni komentare
            if (str.length() > 0 && str[0] != '#')
                precteno = true;
        }
        return str;

    }
};



#endif	/* _INSTANCEREADER_H */

